#!/bin/bash

## 注意：本文件尽量只定义公共参数与函数，不带任何直接执行逻辑，避免引入多次后会出错
## 引入到其他文件时，请使用source命令，避免引入多次

## 定义系统版本文件
File_LinuxRelease=/etc/os-release
File_RedHatRelease=/etc/redhat-release
File_CentOsRelease=/etc/centos-release
File_DebianVersion=/etc/debian_version
File_OpenCloudOSRelease=/etc/opencloudos-release
File_openEulerRelease=/etc/openEuler-release
File_ArchRelease=/etc/arch-release
File_AlpineRelease=/etc/alpine-release

SYSTEM_PRETTY_NAME="$(cat $File_LinuxRelease | grep -E "^PRETTY_NAME=" | awk -F '=' '{print$2}' | sed "s/[\'\"]//g")"
DEVICE_ARCH="$(uname -m)"
SYSTEM_OS="$(cat $File_LinuxRelease | grep -E "^ID=" | awk -F '=' '{print$2}' | sed "s/[\'\"]//g")"
SYSTEM_NAME="$(cat $File_LinuxRelease | grep -E "^NAME=" | awk -F '=' '{print$2}' | sed "s/[\'\"]//g")"
SYSTEM_VERSION_NUMBER="$(cat $File_LinuxRelease | grep -E "^VERSION_ID=" | awk -F '=' '{print$2}' | sed "s/[\'\"]//g")"
system_full_name="${SYSTEM_PRETTY_NAME:-"${SYSTEM_NAME} ${SYSTEM_VERSION_NUMBER}"}"
date_time="$(date "+%Y-%m-%d %H:%M:%S")"
time_zone="$(timedatectl status 2>/dev/null | grep "Time zone" | awk -F ':' '{print$2}' | awk -F ' ' '{print$1}')"


## 报错退出
function output_error() {
    [ "$1" ] && echo -e "\n$ERROR $1\n"
    exit 
}

## 截取第N个开始及之后的参数进行返回
function get_param_from() {
    local start_index=$1
    shift
    # 检查start_index是否为数字
    if ! [[ "$start_index" =~ ^[0-9]+$ ]]; then
        echo "Error: Start index must be a number."
        return 1
    fi
    # 检查截断位置是否在当前参数列表的范围内
    if [ "$start_index" -ge $# ]; then
        # echo "Error: Start index is out of range."
        # return 1
        echo "$@"
    fi

    echo "${@:start_index}"
}

##检查命令是否安装，并推荐安装
function check_command() {
    if ! command -v "$1" &> /dev/null; then
        local defaultpkg=$2
        local pkg=${defaultpkg:-"$1"}
        echo "未安装 $1 命令！是否尝试自动安装$pkg ？"
        read -r -p "输入y 继续 / 任意键退出：" yn
        case $yn in
        y | Y )
            echo "输入y确认直接安装$pkg，或输入正确包名称进行安装"
            read -r -p "" pkgyn
            if [ "$pkgyn" = "y" ]; then
                install_cmd "$1"
                echo "========== finish install $1 =========="
            else
                install_cmd "$pkgyn"
                echo "========== finish install $pkgyn =========="
            fi
            ;;
        * )
            exit
            ;;
        esac
    fi
}

## 返回或直接退出
function back_exit() {
    read -r -n 1 -p "任意键返回菜单，q直接退出:" param
    if [ "$param" = "q" ]; then
        echo -e "\n" && exit 0
    fi
    sh ./linux-tools.sh
}

# 检测系统类型
detect_os_type() {
    if [ -f $File_LinuxRelease ]; then
        echo "$SYSTEM_OS"
    elif [ -f $File_AlpineRelease ]; then
        echo "alpine"
    elif [ -f $File_ArchRelease ]; then
        echo "arch"
    else
        echo "unknown"
    fi
}

# 自动根据系统类型执行不同的函数，只需要提供对应系统的函数即可自动识别
# 如 提供 demo-ubuntu, demo-centos. 调用时写 execute_base_os demo即可自动检测系统调用对应的方法
# 提供第二个入参决定是否直接运行，如 execute_base_os demo direct 将直接运行demo方法
execute_base_os() {
    local os_type
    os_type="$(detect_os_type)"
    local action_func="$1"
    local isDirect="$2"
    local param
    if [ "$isDirect" = "direct" ]; then
        param=$(get_param_from 3 "$@")
        $action_func "$param"
    elif [ "unknown" == "$os_type" ]; then
        echo "unknown os type"
        back_exit
    else
        local func="$action_func-$os_type"
        if [ -z "$(type -t "$func")" ]; then
            echo "Function $func not implemented. unsupported os $os_type"
            back_exit
        fi
        param=$(get_param_from 2 "$@")
        $func "$param"
    fi
}

    # case "$os_type" in
    #     "Ubuntu" | "ubuntu")
    #         "$action_func-$os_type"
    #         ;;
    #     "Debian" | "debian")
    #         "$action_func-$os_type"
    #         ;;
    #     "Centos" | "centos")
    #         "$action_func-$os_type"
    #         ;;
    #     *)
    #         echo "Unsupported OS type: $os_type"
    #         return 1
    #         ;;
    # esac

# 检测系统包管理器
detect_package_manager() {
    if command -v yum >/dev/null 2>&1; then
        PKG_MANAGER="yum"
    elif command -v apt >/dev/null 2>&1; then
        PKG_MANAGER="apt"
    elif command -v pacman >/dev/null 2>&1; then
        PKG_MANAGER="pacman"
    else
        echo "Unsupported package manager. Please install a supported package manager."
        exit 1
    fi
}

detect_package_manager

# 安装软件包的函数
install_cmd() {
    case "$PKG_MANAGER" in
        yum)
            yum install -y "$@"
            ;;
        apt)
            apt-get install -y "$@"
            ;;
        pacman)
            pacman -S -y "$@"
            ;;
        *)
            echo "Package manager not detected. Cannot install packages."
            exit 1
            ;;
    esac
}

# 卸载软件包的函数
uninstall_cmd() {
    case "$PKG_MANAGER" in
        yum)
            yum remove -y "$@"
            ;;
        apt)
            apt-get remove -y "$@"
            ;;
        *)
            echo "Package manager not detected. Cannot uninstall packages."
            exit 1
            ;;
    esac
}

###############
# Name: 获取第一个存在的路径
# Params: <Path Path...> 路径
###############
function get_first_exist_path () {
    for Path in "$@"
    do
        [ -e "${Path}" ] && echo "${Path}" && return 0
    done
    return 1
}

###############
# Name: 获取字符串数组元素
# Params 1: <String> 字符串
# Params 2: <Delimiter> 定界符
# Params 3: <Index> 索引
###############
function get_string_array_item () {
    Str=${1}
    Delimiter=${2}
    Index=${3}
    Arr=("${Str//$Delimiter/}")
    echo "${Arr[$Index]}"
}

###############
# Name: 获取数组第一个相同的元素
# Params 1: <String> 字符串
# Params 2: <Delimiter> 定界符
# Params 3: <Index> 索引
###############
function get_array_first_identical () {
    Array1=("$1")
    Array2=("$2")

    for Item1 in "${Array1[@]}"
    do
        for Item2 in "${Array2[@]}"
        do
            if [ "${Item1}" == "${Item2}" ]; then
                echo "${Item1}"
                return 0
            fi
        done
    done

    return 1
}

###############
# Name: 获取平台类型
###############
function get_platform_type () {
    # ARM 处理器
    case $(uname -m) in
        armv5*) echo "armv5 arm" return 0;;
		armv6*) echo "armv6 arm" return 0;;
		armv7*) echo "armv7 arm" return 0;;
		armv8*) echo "armv8 arm64" return 0;;
		aarch64) echo "arm64";;
	esac
    # 是否 64 位系统
    if [ "$(getconf WORD_BIT)" == "32" ] && [ "$(getconf LONG_BIT)" == "64" ]; then
        is_64bit=y
    else
        is_64bit=n
    fi
    # 是否为 ARM
    if uname -m | grep -Eqi "arm"; then
        is_arm=y
    fi
    # 开始组装合适的返回码
    if [ "${is_arm}" == "y" ]; then
        if [ "${is_64bit}" == "y" ]; then
            echo "arm64"
        else
            echo "arm"
        fi
    else
        if [ "${is_64bit}" == "y" ]; then
            echo "amd64 x64 x86_64 x86-64"
        else
            echo "386 x86 i386"
        fi
    fi
}
